﻿using System;
using System.Drawing;
using System.Windows.Forms;

namespace TestApp
{
    public class RichTextBoxWriter : IConsoleWriter
    {
        RichTextBox richTextBox;
        Color foreColor;

        public RichTextBoxWriter(RichTextBox richTextBox)
        {
            this.richTextBox = richTextBox;
            this.foreColor = richTextBox.ForeColor;
        }

        public void Write(string format)
        {
            WriteAsync(false, this.foreColor, format, 0, 0, 0);
        }

        public void Write(string format, object arg0)
        {
            WriteAsync(false, this.foreColor, format, arg0, 0, 0);
        }

        public void Write(string format, params object[] args)
        {
            WriteAsync(false, this.foreColor, format, args);
        }

        public void Write(Color color, string format)
        {
            WriteAsync(false, color, format, 0, 0, 0);
        }

        public void Write(Color color, string format, object arg0)
        {
            WriteAsync(false, color, format, arg0, 0, 0);
        }

        public void Write(Color color, string format, params object[] args)
        {
            WriteAsync(false, color, format, args);
        }

        public void WriteLine()
        {
            WriteAsync(true, this.foreColor, String.Empty, 0, 0, 0);
        }

        public void WriteLine(string format)
        {
            WriteAsync(true, this.foreColor, format, 0, 0, 0);
        }

        public void WriteLine(string format, object arg0)
        {
            WriteAsync(true, this.foreColor, format, arg0, 0, 0);
        }

        public void WriteLine(string format, params object[] args)
        {
            WriteAsync(true, this.foreColor, format, args);
        }

        public void WriteLine(Color color, string format)
        {
            WriteAsync(true, color, format, 0, 0, 0);
        }

        public void WriteLine(Color color, string format, object arg0)
        {
            WriteAsync(true, color, format, arg0, 0, 0);
        }

        public void WriteLine(Color color, string format, params object[] args)
        {
            WriteAsync(true, color, format, args);
        }

        private void WriteAsync(bool newLine, Color color, string format, params object[] args)
        {
            Action writeAction = () =>
            {
                var str = String.Format(format, args);

                richTextBox.SelectionColor = color;
                richTextBox.AppendText(str);
                richTextBox.SelectionColor = this.foreColor;

                if (newLine)
                {
                    richTextBox.AppendText(Environment.NewLine);
                    str += Environment.NewLine;
                }
            };

            if (richTextBox.InvokeRequired)
            {
                richTextBox.Invoke(writeAction);
            }
            else
            {
                writeAction();
            }
        }
    }
}
